package channelService

import (
	".go-fox-edge-channel-s7-client/channelEntity"
	".go-fox-edge-channel-s7-client/channelEvent"
	"errors"
	"gitee.com/fierce_wolf/go-fox-edge-channel-common/channelStatus"
	"gitee.com/fierce_wolf/go-fox-edge-common/commRedisRpc"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Json"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Map"
	"gitee.com/fierce_wolf/go-fox-edge-common/commUtil/Method"
	"sync"
)

type channelService struct {
	channelName2Entity sync.Map
}

func (e *channelService) getChannelNames() map[string]interface{} {
	result := make(map[string]interface{})
	service.channelName2Entity.Range(func(key, ctx interface{}) bool {
		result[key.(string)] = ctx
		return true
	})

	return result
}

func (e *channelService) OpenChannel(channelName string, channelParam map[string]interface{}) error {
	ip := Map.GetString(channelParam, "ip", "127.0.0.1")
	rack := Map.GetInt(channelParam, "rack", 0)
	slot := Map.GetInt(channelParam, "slot", 1)

	channelStatus.Param.UpdateParamStatus(channelName, "connected", false)

	// 检查：参数是否为空
	if Method.HasEmpty(ip) || Map.HasNull(channelParam, "rack", "slot") {
		return errors.New("参数不能为空: host, rack, slot")
	}

	entity := &channelEntity.S7ClientEntity{}
	entity.ChannelName = channelName
	entity.IP = ip
	entity.Rack = rack
	entity.Slot = slot

	e.channelName2Entity.Store(channelName, entity)

	return nil
}

func (e *channelService) CloseChannel(channelName string, channelParam map[string]interface{}) error {
	// 取出对应的实体信息
	val, ok := e.channelName2Entity.Load(channelName)
	if !ok {
		return nil
	}
	entity := val.(*channelEntity.S7ClientEntity)

	// 删除记录
	e.channelName2Entity.Delete(channelName)

	// 通知失效掉数据
	channelEvent.Invalid.Notify(Json.BuildJson(entity))
	return nil
}

func (e *channelService) Execute(requestVO *commRedisRpc.ChannelRequestVO) (*commRedisRpc.ChannelRespondVO, error) {
	// 取出对应的实体信息
	val, ok := e.channelName2Entity.Load(requestVO.Name)
	if !ok {
		return nil, errors.New("找不到对应的S7Client实体")
	}
	clientEntity := val.(*channelEntity.S7ClientEntity)

	return execute.execute(clientEntity, requestVO)
}
